From 4a10e13111a0417d4c9f2d4ee2ce65955ef745d5 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 22 Jan 2009 11:11:10 +0000 Subject: [PATCH] x86 ucode: microcode logic update Update microcode logic: 1. separate microcode_fini_cpu() into 2 level to avoid deadlock (when fail at microcode_update_cpu); 2. cancel redundant collect_cpu_info at microcode.c level, use relative function at microcode driver level; 3. separate microcode_resume_cpu from microcode_update_cpu, because it's redundant (should only be called when S3 wakeup) and will block newer microcode update when user update newer microcode.dat from user level Signed-off-by: Liu, Jinsong --- xen/arch/x86/microcode.c | 33 ++++++++++++--------------------- xen/arch/x86/microcode_intel.c | 2 ++ 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index b6eacda59b..80526a6103 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -49,25 +49,22 @@ struct microcode_info { char buffer[1]; }; -static void microcode_fini_cpu(int cpu) +static void __microcode_fini_cpu(int cpu) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - spin_lock(µcode_mutex); xfree(uci->mc.mc_valid); - uci->mc.mc_valid = NULL; - spin_unlock(µcode_mutex); + memset(uci, 0, sizeof(*uci)); } -static int collect_cpu_info(int cpu) +static void microcode_fini_cpu(int cpu) { - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - memset(uci, 0, sizeof(*uci)); - return microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + spin_lock(µcode_mutex); + __microcode_fini_cpu(cpu); + spin_unlock(µcode_mutex); } -static int microcode_resume_cpu(int cpu) +int microcode_resume_cpu(int cpu) { int err = 0; struct ucode_cpu_info *uci = ucode_cpu_info + cpu; @@ -107,17 +104,11 @@ static int microcode_update_cpu(const void *buf, size_t size) spin_lock(µcode_mutex); - /* - * Check if the system resume is in progress (uci->mc.mc_valid != NULL), - * otherwise just request a firmware: - */ - if ( uci->mc.mc_valid ) { - err = microcode_resume_cpu(cpu); - } else { - err = collect_cpu_info(cpu); - if ( !err ) - err = microcode_ops->cpu_request_microcode(cpu, buf, size); - } + err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + if ( likely(!err) ) + err = microcode_ops->cpu_request_microcode(cpu, buf, size); + else + __microcode_fini_cpu(cpu); spin_unlock(µcode_mutex); diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c index 4efd679660..8681a6945f 100644 --- a/xen/arch/x86/microcode_intel.c +++ b/xen/arch/x86/microcode_intel.c @@ -64,6 +64,8 @@ static int collect_cpu_info(int cpu_num, struct cpu_signature *csig) struct cpuinfo_x86 *c = &cpu_data[cpu_num]; unsigned int val[2]; + BUG_ON(cpu_num != smp_processor_id()); + memset(csig, 0, sizeof(*csig)); if ( (c->x86_vendor != X86_VENDOR_INTEL) || (c->x86 < 6) || -- 2.30.2